#pragma once
#include "thread.hpp"          // 包含线程类的头文件
#include "LockGuard.hpp"        // 包含锁保护类的头文件（可能是对mutex的封装）
#include <vector>               // 包含vector容器的头文件
#include <queue>                // 包含queue容器的头文件
#include <pthread.h>            // 包含pthread库（POSIX线程库）的头文件
#include <mutex>                // 包含C++标准库中的mutex类，用于锁操作

using namespace ThreadNs;       // 使用ThreadNs命名空间，假设它包含线程相关的定义

const int gnum = 3;            // 定义线程池的默认线程数量为3




// ThreadPool类的前向声明
template <class T>
class ThreadPool;

// ThreadData类，用来存储每个线程的相关数据
template <class T>
class ThreadData
{
public:
    // 构造函数，接收一个线程池指针和线程的名字
    ThreadData(ThreadPool<T> *tp, const std::string &n)
        : threadpool(tp), _name(n)  // 初始化线程池和线程名字
    {
    }

    ThreadPool<T> *threadpool;    // 线程池的指针
    std::string _name;            // 线程名字
};




// ThreadPool类，线程池模板类
template <class T>
class ThreadPool
{
private:
    // 构造函数，初始化线程池，num为线程数，默认为gnum（即3个线程）
    ThreadPool(const int &num = gnum) : _num(num)
    {
        pthread_mutex_init(&_mutex, nullptr);      // 初始化互斥锁
        pthread_cond_init(&_cond, nullptr);        // 初始化条件变量

        // 创建线程对象并加入线程池
        for (int i = 0; i < _num; i++)
        {
            _threads.push_back(new Thread());  // 假设Thread类在其他地方定义
        }
    }

    // 禁止赋值和拷贝构造函数，避免线程池被错误拷贝
    ThreadPool<T>& operator=(const ThreadPool<T> &) = delete;
    ThreadPool(const ThreadPool<T> &) = delete;

    // 静态方法，用来处理任务
    static void *handlerTask(void *args)
    {
        // 将传入的void*参数转换为ThreadData类型
        ThreadData<T> *td = static_cast<ThreadData<T> *>(args);

        while (1)  // 无限循环，不断处理任务
        {
            T t;
            {
                // 获取锁，访问线程池任务队列
                LockGuard lockguard(td->threadpool->mutex());

                // 如果任务队列为空，则等待任务
                while (td->threadpool->isQueueEmpty())
                {
                    td->threadpool->threadWait();  // 线程等待
                }

                // 从队列中取出任务
                t = td->threadpool->pop();
            }

            // 处理任务并输出信息
            std::cout << td->_name << " 获取任务: " << t.toTeskString() << " 处理: " << t() << std::endl;
        }

        // 删除ThreadData对象
        delete td;
        return nullptr;
    }

private:
    // 加锁操作
    void lockQueue()
    {
        pthread_mutex_lock(&_mutex);
    }

    // 解锁操作
    void unlockQueue()
    {
        pthread_mutex_unlock(&_mutex);
    }

    // 判断任务队列是否为空
    bool isQueueEmpty()
    {
        return _TaskQueue.empty();
    }

    // 线程等待操作
    void threadWait()
    {
        pthread_cond_wait(&_cond, &_mutex);  // 线程等待条件变量
    }

    // 从任务队列中取出一个任务
    T pop()
    {
        T t = _TaskQueue.front();
        _TaskQueue.pop();  // 弹出队列中的第一个任务
        return t;
    }

    // 获取互斥锁
    pthread_mutex_t* mutex()
    {
        return &_mutex;
    }

public:
    // 启动线程池，创建并启动线程
    void run()
    {
        for (const auto &t : _threads)  // 遍历每个线程
        {
            // 创建线程数据并传入线程池信息
            ThreadData<T> *td = new ThreadData<T>(this, t->threadname());
            
            // 启动线程，并指定处理函数handlerTask
            t->start(handlerTask, td);
            std::cout << t->threadname() << " start..." << std::endl;
        }
    }

    // 向任务队列中推送任务
    void push(const T &in)
    {
        LockGuard lockguard(&_mutex);  // 获取锁
        _TaskQueue.push(in);           // 将任务加入队列
        pthread_cond_signal(&_cond);   // 唤醒一个等待的线程
    }

    // 析构函数，清理资源
    ~ThreadPool()
    {
        pthread_mutex_destroy(&_mutex);  // 销毁互斥锁
        pthread_cond_destroy(&_cond);    // 销毁条件变量

        for (const auto &t : _threads)  // 删除线程对象
        {
            delete t;
        }
    }

    // 获取线程池的单例实例
    static ThreadPool<T> *getinstance()
    {
        if (tp == nullptr)  // 如果单例还没有创建
        {
            _singlock.lock();  // 获取锁，确保线程安全
            if (tp == nullptr)  // 再次检查是否还没创建
            {
                tp = new ThreadPool<T>();  // 创建线程池实例
            }
            _singlock.unlock();  // 释放锁
            return tp;
        }
    }

private:
    int _num;                        // 线程池中的线程数
    std::vector<Thread *> _threads;   // 线程池中的线程集合
    std::queue<T> _TaskQueue;         // 任务队列，用于存放任务
    pthread_mutex_t _mutex;           // 互斥锁，保护任务队列
    pthread_cond_t _cond;             // 条件变量，用于线程同步

    static ThreadPool<T> *tp;         // 线程池单例实例
    static std::mutex _singlock;      // 用于保护单例的锁
};

// 初始化静态成员变量
template <class T>
ThreadPool<T> *ThreadPool<T>::tp = nullptr;

template <class T>
std::mutex ThreadPool<T>::_singlock;  // 静态互斥锁
